package net.nagaseyasuhito.nicola;

import net.nagaseyasuhito.nicola.page.IndexPage;
import net.nagaseyasuhito.nicola.page.MyPage;
import net.nagaseyasuhito.nicola.page.SignInPage;
import net.nagaseyasuhito.nicola.page.SignUpPage;
import net.nagaseyasuhito.nicola.page.UserPage;

import org.apache.wicket.authentication.AuthenticatedWebApplication;
import org.apache.wicket.authentication.AuthenticatedWebSession;
import org.apache.wicket.guice.GuiceInjectorHolder;
import org.apache.wicket.markup.html.WebPage;

import com.google.inject.AbstractModule;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.wideplay.warp.jpa.JpaUnit;
import com.wideplay.warp.persist.PersistenceService;
import com.wideplay.warp.persist.TransactionStrategy;
import com.wideplay.warp.persist.UnitOfWork;

public class NicolaWebApplication extends AuthenticatedWebApplication {

	public static NicolaWebApplication get() {
		return (NicolaWebApplication) AuthenticatedWebApplication.get();
	}

	@Override
	protected void init() {
		super.init();
		this.initGuice();
		this.mountBookmarkablePages();
		
		this.getMarkupSettings().setStripWicketTags(true);
	}

	private void initGuice() {
		Module persistenceServiceModule = 
			PersistenceService
				.usingJpa()
				.across(UnitOfWork.REQUEST)
				.transactedWith(TransactionStrategy.LOCAL)
				.buildModule();
		Module persistenceServiceInitializeModule = new AbstractModule() {
			@Override
			protected void configure() {
				this.bindConstant().annotatedWith(JpaUnit.class).to("persistenceUnit");
			}
		};

		NicolaGuiceComponentInjector guiceComponentInjector = new NicolaGuiceComponentInjector(this, persistenceServiceModule, persistenceServiceInitializeModule);
		this.getInjector().getInstance(PersistenceService.class).start();

		this.addComponentInstantiationListener(guiceComponentInjector);
		this.addComponentOnBeforeRenderListener(guiceComponentInjector);
	}

	private void mountBookmarkablePages() {
		this.mountBookmarkablePage("/my", MyPage.class);
		this.mountBookmarkablePage("/user", UserPage.class);
		this.mountBookmarkablePage("/signUp", SignUpPage.class);
	}

	@Override
	protected Class<? extends WebPage> getSignInPageClass() {
		return SignInPage.class;
	}

	@Override
	protected Class<? extends AuthenticatedWebSession> getWebSessionClass() {
		return NicolaSession.class;
	}

	@Override
	public Class<? extends WebPage> getHomePage() {
		return IndexPage.class;
	}

	public Injector getInjector() {
		return ((GuiceInjectorHolder) this.getMetaData(GuiceInjectorHolder.INJECTOR_KEY)).getInjector();
	}
}
